﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.Globalization;

namespace LostLib.Programs
{
	/// <summary>
	/// Some shell extensions
	/// </summary>
	public static class ShellExtensions
	{
		/// <summary>
		/// Performs specified action on file system entry.
		/// </summary>
		/// <param name="entry">An entry to be accessed.</param>
		/// <param name="verb">An action to perform.</param>
		[Obsolete("This will be removed in future versions")]
		public static void PerformAction(this FileSystemInfo entry, string verb)
		{
			ProcessStartInfo startInfo;
			var imt = entry.GetMediaType();
			if (imt.Equals(new InternetMediaType("application", "x", "msi")))
			{
				switch (verb)
				{
				case "silent install":
					//MSI.Installer.SetInternalUI(2, IntPtr.Zero);
					startInfo = new ProcessStartInfo("msiexec");
					startInfo.UseShellExecute = false;
					startInfo.RedirectStandardOutput = true;
					startInfo.RedirectStandardError = true;
					startInfo.CreateNoWindow = true;
					startInfo.Arguments = string.Format( CultureInfo.InvariantCulture, "/quiet /i \"{0}\"", entry.FullName);
					using (var process = Process.Start(startInfo))
					using (var stream = process.StandardOutput)
					using (var errorStream = process.StandardError)
					{
						var error = errorStream.ReadToEnd();
						process.WaitForExit();
						if (process.ExitCode != 0)
							throw new OperationCanceledException(
								string.Format(CultureInfo.CurrentCulture, "installing {0} failed with exit code {1}\n{2}", entry.Name, process.ExitCode, error));
					}										  
					return;

				case "silent remove":
					startInfo = new ProcessStartInfo("msiexec");
					startInfo.UseShellExecute = false;
					//startInfo.RedirectStandardOutput = true;
					startInfo.Arguments = string.Format(CultureInfo.InvariantCulture, "/quiet /x \"{0}\"", entry.FullName);
					using (var process = Process.Start(startInfo))
					//using (var stream = process.StandardOutput)
					{
					//    var error = stream.ReadToEnd();
						process.WaitForExit();
						if (process.ExitCode != 0)
							throw new OperationCanceledException(
								string.Format(CultureInfo.CurrentCulture, "removing {0} failed with exit code {1}", entry.Name, process.ExitCode));
					}
					return;
				}
				
			}
			startInfo = new ProcessStartInfo(entry.FullName);
			bool can = false;
			foreach (var fileVerb in startInfo.Verbs)
				if (fileVerb == verb) can = true;
			if (!can) throw new NotSupportedException(
				string.Format(CultureInfo.CurrentCulture, "Verb {0} is not supported for {1}", verb, entry.Name));

			using (var process = Process.Start(startInfo)) { }
		}
	}
}
